
#ifndef _data_types_h
#define _data_types_h

#include <mpi.h>

#ifndef NULL
  #define NULL 0 // <cstddef> - not found
#endif

#define CONTAINER_TYPE float // CMake variable???

template <class T>
class PAIR : public std::pair<T, T> {
 private:
   static T minus_one;
    
 public:
   PAIR() : std::pair<T, T>() {}
   PAIR(T x, T y) : std::pair<T, T>(x, y) {}
   T& operator[](const int index) {
     switch (index) {
       case 0:
	 return std::pair<T, T>::first;
       case 1:
	 return std::pair<T, T>::second;
       default:
	 return minus_one;
     }
   }

   bool operator<(const PAIR <T>& val) {
     if ((*this)[0]<val[0])
       return true;
     else if (val[0]>(*this)[0])
       return false;

     if ((*this)[1]<val[0])
       return true;
     else if (val[0]>(*this)[0])
       return false;

     return false;
   }
 };

typedef PAIR<int> INT_PAIR;
typedef PAIR<float> FLT_PAIR;
typedef PAIR<double> DBL_PAIR;

typedef struct {
  int offset[2]; // 0 -> (j, x) 1 -> (i, y)
  int extent[2];
  int id[2];
} blk_meta_data; 

class DataTypes {
  public:
    static MPI_Datatype MPI_BLK_META_DATA;
    static int init();
};

#endif
